package staticdemo;

/**
 * static修饰符使用详解
 * 
 * static是Java中的一个重要关键字，它可以修饰变量、方法、代码块和内部类。
 * 被static修饰的成员属于类本身，而不是类的实例。
 */
public class StaticDemo {
    
    // 静态变量（类变量）- 属于类，所有实例共享
    private static int staticVar = 0;
    
    // 实例变量 - 属于实例，每个实例都有自己的副本
    private int instanceVar = 0;
    
    // 静态常量
    public static final String CONSTANT = "这是一个静态常量";
    
    // 静态代码块 - 类加载时执行，且只执行一次
    static {
        System.out.println("静态代码块被执行");
        staticVar = 100;
    }
    
    // 实例代码块 - 每次创建实例时执行
    {
        System.out.println("实例代码块被执行");
        instanceVar = 10;
    }
    
    // 构造函数
    public StaticDemo() {
        System.out.println("构造函数被执行");
        staticVar++;
        instanceVar++;
    }
    
    // 静态方法
    public static void staticMethod() {
        System.out.println("静态方法被调用，staticVar = " + staticVar);
        // 静态方法不能直接访问实例变量
//         System.out.println(instanceVar); // 编译错误
    }
    
    // 实例方法
    public void instanceMethod() {
        System.out.println("实例方法被调用，staticVar = " + staticVar + ", instanceVar = " + instanceVar);
        // 实例方法可以访问静态变量和实例变量
    }
    
    // 静态方法访问实例变量的正确方式 - 通过实例引用
    public static void staticMethodWithInstance(StaticDemo demo) {
        System.out.println("通过实例引用访问instanceVar = " + demo.instanceVar);
    }
    
    // Getter方法
    public int getInstanceVar() {
        return instanceVar;
    }
    
    public static int getStaticVar() {
        return staticVar;
    }
    
    /**
     * 主方法，演示static修饰符的使用
     */
    public static void main(String[] args) {
        System.out.println("=== static修饰符使用详解 ===\n");

        System.out.println("1. 静态变量和实例变量的区别：");
        System.out.println("初始状态 - staticVar = " + StaticDemo.getStaticVar());
        System.out.println("初始状态 - staticVar = " + StaticDemo.staticVar);

        // 创建第一个实例
        System.out.println("\n创建第一个实例:");
        StaticDemo demo1 = new StaticDemo();
        System.out.println("demo1 - staticVar = " + demo1.getStaticVar() + ", instanceVar = " + demo1.getInstanceVar());

        // 创建第二个实例
        System.out.println("\n创建第二个实例:");
        StaticDemo demo2 = new StaticDemo();
        System.out.println("demo2 - staticVar = " + demo2.getStaticVar() + ", instanceVar = " + demo2.getInstanceVar());
        System.out.println("demo1 - staticVar = " + demo1.getStaticVar() + ", instanceVar = " + demo1.getInstanceVar());

        System.out.println("\n可以看到，静态变量被所有实例共享，而实例变量每个实例都有自己的副本。\n");

        System.out.println("2. 静态方法和实例方法的区别：");
        // 调用静态方法 - 通过类名调用
        StaticDemo.staticMethod();

        // 调用实例方法 - 通过实例调用
        demo1.instanceMethod();
        demo2.instanceMethod();

        System.out.println("\n静态方法可以通过类名直接调用，不需要创建实例。\n");

        System.out.println("3. 静态常量的使用：");
        System.out.println("CONSTANT = " + StaticDemo.CONSTANT);
        // 常量不能被修改
        // StaticDemo.CONSTANT = "new value"; // 编译错误

        System.out.println("\n4. 静态方法访问实例变量：");
        StaticDemo.staticMethodWithInstance(demo1);

        System.out.println("\n=== 静态导入演示 ===");
        // 参见另一个类StaticImportDemo
    }
}